package com.Lyoto.core.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;

/**
 * @author Lyoto
 * @Description
 * @Date 2022-09-21 18:53
 * @Version
 **/
@Component
public class RedisConfiguration {
    @Bean
    public DefaultRedisScript<Number> redisScript(){
        String luaScript = "local key = \"rate.limit\" ..KEYS[1]\n" +
                "local limit = tonumber(ARGV[1])\n" +
                "local current = tonumber(redis.call('get',key) or \"0\")\n" +
                "if current +1 > limit then\n" +
                "return 0\n" +
                "else\n" +
                "redis.call('INCRBY',key,'1')\n" +
                "redis.call('expire',key,'2')\n" +
                "return current + 1\n" +
                "end";
        return new DefaultRedisScript<>(luaScript,Number.class);
    }
    @Bean("customRedisTemplate")
    public <K,V> RedisTemplate<K,V> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<K, V> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);

        redisTemplate.setValueSerializer(objectJackson2JsonRedisSerializer);
        redisTemplate.setKeySerializer(new StringRedisSerializer());

        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }
}
